package com.hbnu.system.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hbnu.system.config.BaseException;
import com.hbnu.system.constant.RoleConstant;
import com.hbnu.system.constant.StatusCheckConstant;
import com.hbnu.system.core.base.CommonPage;
import com.hbnu.system.core.service.IBeanService;
import com.hbnu.system.mapper.WorkMapper;
import com.hbnu.system.model.context.BaseContext;
import com.hbnu.system.model.dto.CheckBackDTO;
import com.hbnu.system.model.dto.WorkDTO;
import com.hbnu.system.model.entity.*;
import com.hbnu.system.model.query.WorkPageQuery;
import com.hbnu.system.service.*;
import com.hbnu.system.utils.CheckAuditHelper;
import com.hbnu.system.utils.CheckRoleUtil;
import com.hbnu.system.utils.UserInfoUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author ${author}
 * @since 2023-05-16
 */
@Service
public class WorkServiceImpl extends ServiceImpl<WorkMapper, Work> implements IWorkService {

    @Autowired
    private IBeanService iBeanService;
    @Autowired
    private IWorkService iWorkService;
    @Autowired
    private IUserService iUserService;
    @Autowired
    private IWorkQualificationService iWorkQualificationService;
    @Autowired
    private IAuthorityService iAuthorityService;
    @Autowired
    private AuditService auditService;
    @Autowired
    private IdToStatsService idToStatsService;
    @Autowired
    IDeptService iDeptService;
    @Autowired
    private IWorkfileService iWorkfileService;
    @Autowired
    private WorkMapper workMapper;
    @Autowired
    private IWorkauthorService iWorkauthorService;
    @Autowired
    private CheckRoleUtil checkRoleUtil;
    @Autowired
    private UserInfoUtils userInfoUtils;
    @Autowired
    private IWorkprojectService iworkprojectService;
    @Override
    public boolean checkWorkname(String name){
        Work one = super.getOne(Wrappers.lambdaQuery(Work.class)
                .eq(Work::getWorkname, name));
        if(Objects.nonNull(one)){
            throw new BaseException("该著作名称已存在!");
        }
        return true;
    }

    /**
     * 新增著作
     * @param work
     * @return
     */
    @Override
    public boolean addnewwork(Work work) {
        if (StrUtil.isEmpty(work.getWorkname()) || StrUtil.isBlank(work.getWorkname())){
            throw new BaseException("请输入著作名!");
        }
        if (StrUtil.isEmpty(work.getPressname()) || StrUtil.isBlank(work.getPressname())){
            throw new BaseException("请输入出版社名称!");
        }
        if (StrUtil.isEmpty(work.getPublicplace()) || StrUtil.isBlank(work.getPublicplace())){
            throw new BaseException("请输入出版地!");
        }
        if(StrUtil.isEmpty(work.getEntered()) || StrUtil.isBlank(work.getEntered())){
            throw new BaseException("请输入录入人");
        }
        if (StrUtil.isEmpty(work.getStandardnumber()) || StrUtil.isBlank(work.getStandardnumber())){
            throw new BaseException("请输入ISSN或ISBN!");
        }
        Work one = super.getOne(Wrappers.lambdaQuery(Work.class).eq(Work::getWorkname, work.getWorkname()));
        if (Objects.nonNull(one)&& !(one.getWorkID().equals(work.getWorkID()))) {
            throw new BaseException("该著作名已被使用");
        }

        work.setStatus("草稿");
        if (StrUtil.isEmpty(work.getLeadauthor()) || StrUtil.isBlank(work.getLeadauthor())){
            work.setLeadauthor("");
        }
        if (StrUtil.isEmpty(work.getCorrespondingAuthor()) || StrUtil.isBlank(work.getCorrespondingAuthor())){
            work.setCorrespondingAuthor("");
        }
        work.setEntereddate(LocalDateTime.now());
        return baseMapper.insert(work) == 1;
    }

    /**
     * 修改著作
     * @param work
     * @return
     */
    @Override
    public boolean updatework(Work work) {
        checkRoleUtil.checkPermissionAchievement(work.getStatus());

        if (StrUtil.isEmpty(work.getWorkname()) || StrUtil.isBlank(work.getWorkname())){
            throw new BaseException("请输入著作名!");
        }
        if (StrUtil.isEmpty(work.getPressname()) || StrUtil.isBlank(work.getPressname())){
            throw new BaseException("请输入出版社名称!");
        }

        //判断著作名是否修改重复
        Work one = super.getOne(Wrappers.lambdaQuery(Work.class)
                .eq(Work::getWorkname, work.getWorkname())
                .ne(Work::getWorkID, work.getWorkID()));
        if (Objects.nonNull(one)) {
            throw new BaseException("该著作名已被使用");
        }

        return baseMapper.updateById(work) == 1;
    }

    /**
     * 删除作品
     * @param workID 著作id
     * @return
     * @throws IOException
     */
    @Override
    @Transactional
    public boolean deletework(String workID) throws IOException {
        // 校验普通用户权限不能修改当前状态信息
        Work work = super.getOne(Wrappers.lambdaQuery(Work.class)
                .eq(Work::getWorkID, workID));
        checkRoleUtil.checkPermissionAchievement(work.getStatus());

        // 删除著作关联的作者根据著作id
        iWorkauthorService.remove(Wrappers.lambdaQuery(Workauthor.class)
                .eq(Workauthor::getWorkID, workID));

        // 删除著作关联的文件信息根据著作id
        iWorkfileService.remove(Wrappers.lambdaQuery(Workfile.class)
                .eq(Workfile::getWorkid, workID));

        // 删除著作关联的量化分数根据著作id
        iWorkQualificationService.remove(Wrappers.lambdaQuery(Work_Qualification.class)
                .eq(Work_Qualification::getWorkID, workID));

        // 删除文件信息
        List<Workfile> workFiles = iWorkfileService.list(Wrappers.lambdaQuery(Workfile.class)
                .eq(Workfile::getWorkid, workID));
        List<String> fileIds = workFiles.stream()
                .map(Workfile::getFileid)
                .collect(Collectors.toList());
        for (String fileId : fileIds) {
            iWorkfileService.deletWorkfile(fileId);
        }
        // 删除审核记录根据著作ID
        auditService.remove(Wrappers.lambdaQuery(Audit.class)
                .eq(Audit::getSynthesisID, workID));

        // 最后删除著作本身
        return baseMapper.deleteById(workID) == 1;
    }




    @Override
    public Work getWork(String id) {
        Work work = super.getOne(Wrappers.lambdaQuery(Work.class)
                .eq(Work::getWorkID, id));
        if (Objects.isNull(work)) {
            throw new BaseException("著作编号异常!未查找到该著作");
        }
        return work;

    }

    @Override
    public WorkDTO getWorkDTOById(String id) {
        Work work = super.getOne(Wrappers.lambdaQuery(Work.class)
                .eq(Work::getWorkID, id));
        if (Objects.isNull(work)) {
            throw new BaseException("著作编号异常!未查找到该著作");
        }

        String entered = idToStatsService.IdToName(work.getEntered());
        String dept=idToStatsService.IdToDept(work.getDept());
        String allAuthor=idToStatsService.IdToAllauthor(work.getAllauthor());

        WorkDTO workdto = new WorkDTO();
        BeanUtils.copyProperties(work,workdto);

        workdto.setAllauthorName(allAuthor);
        workdto.setEnteredName(entered);
        workdto.setDeptName(dept);

        return workdto;

    }


    @Autowired
    private CheckAuditHelper checkAuditHelper;

    @Override
    public Boolean collegeCheckPass(String token, String PID) {
        Work work = iWorkService.getWork(PID);
        if (work == null) {
            throw new BaseException("该著作编号有误!");
        }

        String roleName = userInfoUtils.getCurrentUserInfo().getRoleName();

        // 根据角色确定目标状态
        String targetStatus = StatusCheckConstant.COLLEGE_CHECK_PEOPLE.equals(roleName)
                ? StatusCheckConstant.WAIT_SCHOOL_CHECK
                : StatusCheckConstant.CHECK_PASS;

        return checkAuditHelper.doPassAudit(
                work,
                StatusCheckConstant.WAIT_COLLEGE_CHECK,
                targetStatus,
                roleName,
                "著作",
                work::getWorkID,
                work::getStatus,
                work::setStatus,
                this::updateWorkByEntity
        );
    }

    @Override
    public Boolean collegeCheckBack(String token, CheckBackDTO checkBackDTO) {
        Work work = iWorkService.getWork(checkBackDTO.getID());
        if (work == null) {
            throw new BaseException("该著作编号有误!");
        }

        String roleName = userInfoUtils.getCurrentUserInfo().getRoleName();

        String backStatus = StatusCheckConstant.COLLEGE_CHECK_PEOPLE.equals(roleName)
                ? StatusCheckConstant.COLLEGE_CHECK_BACK
                : StatusCheckConstant.SCHOOL_CHECK_BACK;

        return checkAuditHelper.doBackAudit(
                work,
                StatusCheckConstant.WAIT_COLLEGE_CHECK,
                backStatus,
                checkBackDTO.getReason(),
                "著作",
                work::getWorkID,
                work::getStatus,
                work::setStatus,
                work::setReason,
                this::updateWorkByEntity
        );
    }

    @Override
    public Boolean schoolCheckPass(String token, String PID) {
        Work work = iWorkService.getWork(PID);
        if (work == null) {
            throw new BaseException("该著作编号有误!");
        }

        String currentStatus = work.getStatus();
        if (!StatusCheckConstant.WAIT_SCHOOL_CHECK.equals(currentStatus)
                && !StatusCheckConstant.WAIT_COLLEGE_CHECK.equals(currentStatus)) {
            throw new BaseException("该著作状态不处于该环节!");
        }

        String roleName = userInfoUtils.getCurrentUserInfo().getRoleName();

        return checkAuditHelper.doPassAudit(
                work,
                currentStatus,
                StatusCheckConstant.CHECK_PASS,
                roleName,
                "著作",
                work::getWorkID,
                work::getStatus,
                work::setStatus,
                this::updateWorkByEntity
        );
    }

    @Override
    public Boolean schoolCheckBack(String token, CheckBackDTO checkBackDTO) {
        Work work = iWorkService.getWork(checkBackDTO.getID());
        if (work == null) {
            throw new BaseException("该著作编号有误!");
        }

        String currentStatus = work.getStatus();
        if (!StatusCheckConstant.WAIT_SCHOOL_CHECK.equals(currentStatus)
                && !StatusCheckConstant.WAIT_COLLEGE_CHECK.equals(currentStatus)
                && !StatusCheckConstant.CHECK_PASS.equals(currentStatus)) {
            throw new BaseException("该著作状态不处于该环节!");
        }

        String roleName = userInfoUtils.getCurrentUserInfo().getRoleName();

        return checkAuditHelper.doBackAudit(
                work,
                currentStatus,
                StatusCheckConstant.SCHOOL_CHECK_BACK,
                checkBackDTO.getReason(),
                "著作",
                 work::getWorkID,
                work::getStatus,
                work::setStatus,
                work::setReason,
                this::updateWorkByEntity
        );
    }


    /**
     * 著作撤回
     * @param id
     * @return
     */
    @Override
    public Boolean withdrawWork(String id) {
        // 获取当前用户ID
        String userId = BaseContext.getCurrentId();
        User user = iUserService.getById(userId);
        if (user == null) {
            throw new BaseException("用户不存在！");
        }
        
        // 查询著作信息
        Work work = super.getOne(Wrappers.lambdaQuery(Work.class)
                .eq(Work::getWorkID, id));
        if (work == null) {
            throw new BaseException("著作编号异常!未查找到该著作");
        }
        
        // 检查状态是否为院级审核中
        if (!StatusCheckConstant.WAIT_COLLEGE_CHECK.equals(work.getStatus())) {
            throw new BaseException("只有带院级审核状态的情况下才能撤回！");
        }
        
        // 更新状态为草稿
        work.setStatus(StatusCheckConstant.DRAFT);
        return baseMapper.updateById(work) == 1;
    }

    /**
     * 著作提交
     * @param id
     * @return
     */
    @Override
    public Boolean ReCommitWork(String id) {
        Work work = super.getOne(Wrappers.lambdaQuery(Work.class)
                .eq(Work::getWorkID,id));
        //检查字段是否填写
        checkCommitField(work);
        work.setStatus("待院级审核");
        work.setReason("");
        return baseMapper.updateById(work) == 1;
    }

    /**
     * 著作分页查询
     * @param workPageQuery
     * @return
     */
    @Override
    public CommonPage<Work> userGetRelateWork(WorkPageQuery workPageQuery) {
        String userId = BaseContext.getCurrentId();
        User user = iUserService.getById(userId);
        String role = user.getRole();

        // 创建MyBatis-Plus的Page对象
        Page<Work> page = new Page<>(workPageQuery.getPageNum(), workPageQuery.getPageSize());
        IPage<Work> workIPage = null;

        // 根据角色执行不同查询
        if (role.equals(RoleConstant.ROLE_ADMIN_SCHOOL)) {
            workIPage = workMapper.schoolGetRelateWorkQuery(page, workPageQuery, user);
        } else if (role.equals(RoleConstant.ROLE_ADMIN_COLLEGE)) {
            workIPage = workMapper.collegeGetRelateWorkQuery(page, workPageQuery, user);
        } else {
            workIPage = workMapper.userGetRelateWorkQuery(page, workPageQuery, user);
        }

        // 构造返回分页对象
        CommonPage<Work> workCommonPage = CommonPage.restPage(workIPage);
        List<Work> records = workIPage.getRecords();

        // 初始化量化分数
        float figure = 0;


        // 遍历记录，计算量化分数
        for (Work record : records) {
            if (record.getStatus().equals("审核通过")){
                figure += record.getScore();
            }
        }

        workCommonPage.setFigure(figure);
        workCommonPage.setList(records);

        return workCommonPage;
    }

    /**
     * 导出
     * @param workPageQuery 查询条件
     * @return 导出数据
     */
    @Override
    public CommonPage<Work> export(WorkPageQuery workPageQuery) {
        String userId = BaseContext.getCurrentId();
        User user = iUserService.getById(userId);
        String role = user.getRole();

        Page<Work> page = new Page<>(workPageQuery.getPageNum(), workPageQuery.getPageSize());
        IPage<Work> workIPage;

        if (RoleConstant.ROLE_ADMIN_SCHOOL.equals(role)) {
            workIPage = workMapper.schoolExportRelateWorkQuery(page, workPageQuery, user);
        } else if (RoleConstant.ROLE_ADMIN_COLLEGE.equals(role)) {
            workIPage = workMapper.collegeExportRelateWorkQuery(page, workPageQuery, user);
        } else {
            workIPage = workMapper.userExportRelateWorkQuery(page, workPageQuery, user);
        }

        List<Work> records = workIPage.getRecords();

        float figure = 0;
        for (Work record : records) {
            if (StatusCheckConstant.CHECK_PASS.equals(record.getStatus())) {
                figure += record.getScore();
            }

            // 查询第一作者/共同第一作者
            List<Workauthor> leadAuthors = iWorkauthorService.list(Wrappers.lambdaQuery(Workauthor.class)
                    .eq(Workauthor::getWorkID, record.getWorkID())
                    .in(Workauthor::getAuthortype, Arrays.asList("第一作者", "共同第一作者")));
            record.setLeadauthor(leadAuthors.stream().map(Workauthor::getName).collect(Collectors.joining(",")));

            // 查询通讯作者
            List<Workauthor> contactAuthors = iWorkauthorService.list(Wrappers.lambdaQuery(Workauthor.class)
                    .eq(Workauthor::getWorkID, record.getWorkID())
                    .eq(Workauthor::getAuthortype, "通讯作者"));
            record.setCorrespondingAuthor(contactAuthors.stream().map(Workauthor::getName).collect(Collectors.joining(",")));

            // 查询关联项目
            List<Workproject> workProjects = iworkprojectService.list(Wrappers.lambdaQuery(Workproject.class)
                    .eq(Workproject::getWorkID, record.getWorkID()));
            record.setAssociatedprojects(workProjects.stream().map(Workproject::getProjectName).collect(Collectors.joining(",")));
            //转化allAuthors
            String allAuthor = idToStatsService.IdToAllauthor(record.getAllauthor());
            record.setAllauthor(allAuthor);
        }

        CommonPage<Work> workCommonPage = CommonPage.restPage(workIPage);
        workCommonPage.setFigure(figure);
        workCommonPage.setList(records);
        return workCommonPage;
    }




    /**
     * 检查提交字段是否填写
     * @param work
     */
    private void checkCommitField(Work work) {
        if(Objects.isNull(work)){
            throw new BaseException("著作编号有误!");
        }
        if(!work.getStatus().equals("草稿") && !work.getStatus().equals("被校级退回")&& !work.getStatus().equals("被院级退回")){
            throw new BaseException("该著作不适用于该阶段!");
        }
        if (StrUtil.isEmpty(work.getSignedunit()) || StrUtil.isBlank(work.getSignedunit())){
            throw new BaseException("请输入署名单位!");
        }
        if (StrUtil.isEmpty(work.getWorkname()) || StrUtil.isBlank(work.getWorkname())){
            throw new BaseException("请输入著作名称!");
        }
        if (StrUtil.isEmpty(work.getWorkcate()) || StrUtil.isBlank(work.getWorkcate())){
            throw new BaseException("请输入著作类别!");
        }
        if (StrUtil.isEmpty(work.getPressname()) || StrUtil.isBlank(work.getPressname())){
            throw new BaseException("请输入出版社名称!");
        }
        if (StrUtil.isEmpty(work.getPresslevel()) || StrUtil.isBlank(work.getPresslevel())){
            throw new BaseException("请输入出版社级别!");
        }
        if (StrUtil.isEmpty(work.getPublicplace()) || StrUtil.isBlank(work.getPublicplace())){
            throw new BaseException("请输入出版地!");
        }
        if (StrUtil.isEmpty(work.getStandardnumber()) || StrUtil.isBlank(work.getStandardnumber())){
            throw new BaseException("请输入ISSN或ISBN!");
        }
        if (StrUtil.isEmpty(work.getResearchcate()) || StrUtil.isBlank(work.getResearchcate())){
            throw new BaseException("请输入研究类别!");
        }
        if (StrUtil.isEmpty(work.getWorkorigin()) || StrUtil.isBlank(work.getWorkorigin())){
            throw new BaseException("请输入著作来源!");
        }
        if (StrUtil.isEmpty(work.getFirstdiscipline()) || StrUtil.isBlank(work.getFirstdiscipline())){
            throw new BaseException("请输入一级学科!");
        }
        
        // 检查量化分数是否填写
        Work_Qualification qualification = iWorkQualificationService.getOne(
                Wrappers.lambdaQuery(Work_Qualification.class)
                        .eq(Work_Qualification::getWorkID, work.getWorkID())
        );
        if (Objects.isNull(qualification)) {
            throw new BaseException("请先填写著作的量化分数!");
        }
        
        // 检查作者列表是否填写
        List<Workauthor> authorList = iWorkauthorService.list(
                Wrappers.lambdaQuery(Workauthor.class)
                        .eq(Workauthor::getWorkID, work.getWorkID())
        );
        if (CollectionUtils.isEmpty(authorList)) {
            throw new BaseException("请先添加著作的作者信息!");
        }
    }


    /**
     * 更新著作实体到数据库
     */
    private Boolean updateWorkByEntity(Work work) {
        return baseMapper.updateById(work) == 1;
    }


}